home *** CD-ROM | disk | FTP | other *** search
- /*
- ** clip-handler.c
- ** DOS handler for Clipboard access
- ** Copyright © 1995 Michael Letowski
- */
-
- #define __USE_SYSBASE
-
- #include <exec/types.h>
- #include <exec/execbase.h>
- #include <exec/memory.h>
- #include <dos/dos.h>
- #include <dos/dosextens.h>
- #include <dos/filehandler.h>
- #include <libraries/iffparse.h>
- #include <devices/clipboard.h>
- #include <support/types.h>
- #include <support/exec.h>
- #include <support/dos.h>
-
- #include <string.h>
- #include <stdlib.h>
-
- #include <proto/exec.h>
- #include <proto/iffparse.h>
-
- #include "clip-handler.rev.h"
-
- #define DOS_NAME "dos.library"
- #define DOS_VERN 37L
- #define IFFP_NAME "iffparse.library"
- #define IFFP_VERN 37L
- #define CLIP_NAME "clipboard.device"
-
- STATIC CONST TEXT VersionString[]=
- VERSION(PROG_NAME,PROG_VERSION,PROG_REVISION,PROG_DATE);
-
- #define ID_FTXT MAKE_ID('F','T','X','T')
- #define ID_CHRS MAKE_ID('C','H','R','S')
-
- #define PATH_SIZE 256
-
- /* Library bases */
- struct ExecBase *SysBase;
- struct Library *IFFParseBase;
-
- STATIC struct DosPacket *WaitPacket(struct MsgPort *port);
- STATIC VOID ReplyPacket(struct DosPacket *packet, struct MsgPort *port);
- STATIC VOID ReplyPacketRes(struct DosPacket *packet, struct MsgPort *port,
- LONG res1, LONG res2);
- STATIC struct IFFHandle *OpenCH(struct DosPacket *packet);
- STATIC VOID CloseCH(struct IFFHandle *iff);
- STATIC LONG OpenInputCH(struct DosPacket *packet);
- STATIC LONG OpenOutputCH(struct DosPacket *packet);
- STATIC LONG OpenUpdateCH(struct DosPacket *packet);
- STATIC LONG CloseIOUCH(struct DosPacket *packet);
- STATIC VOID ReadClipboard(struct DosPacket *packet);
- STATIC VOID WriteClipboard(struct DosPacket *packet);
- STATIC VOID SeekClipboard(struct DosPacket *packet);
- STATIC LONG IFF2DOS(LONG iffError);
-
- SAVEDS LONG ClipHandler(VOID)
- {
- struct Library *LocalIFFParseBase;
-
- struct Process *PR;
- struct MsgPort *MP,*PacketPort;
- struct DosPacket *Pkt;
- struct DeviceNode *DevNode;
- LBOOL Done=FALSE;
- ULONG OpenCount=0;
-
- SysBase=*((struct ExecBase **)4); /* Set up SysBase */
- PR=ThisProcessS;
- MP=&PR->pr_MsgPort;
-
- if(PR->pr_CLI) /* Run from shell */
- return(RETURN_FAIL); /* Failure */
-
- Pkt=WaitPacket(MP); /* Get startup message */
- try(DevNode=(struct DeviceNode *)BADDR(Pkt->dp_Arg3),NO_DEV);
-
- /* Open IFFParse */
- unless(LocalIFFParseBase=OpenLibrary(IFFP_NAME,IFFP_VERN))
- {
- ReplyPacketRes(Pkt,MP,DOSFALSE,ERROR_INVALID_RESIDENT_LIBRARY);
- throw(NO_IFFPARSE);
- }
- /* Create port */
- unless(PacketPort=CreateMsgPort())
- {
- ReplyPacketRes(Pkt,MP,DOSFALSE,ERROR_NO_FREE_STORE);
- throw(NO_PORT);
- }
- /* Set up global bases */
- IFFParseBase=LocalIFFParseBase; /* Set up global bases */
- DevNode->dn_Task=PacketPort;
- Pkt->dp_Arg4=(LONG)PacketPort;
- ReplyPacketRes(Pkt,PacketPort,DOSTRUE,Pkt->dp_Res2);
-
- while(!Done)
- {
- Pkt=WaitPacket(PacketPort);
- switch(Pkt->dp_Type)
- {
- case ACTION_FINDINPUT:
- OpenCount+=OpenInputCH(Pkt);
- break;
- case ACTION_FINDOUTPUT:
- OpenCount+=OpenOutputCH(Pkt);
- break;
- /* case ACTION_FINDUPDATE:
- OpenCount+=OpenUpdateCH(Pkt);*/
- break;
- case ACTION_END:
- OpenCount-=CloseIOUCH(Pkt);
- break;
- case ACTION_READ:
- ReadClipboard(Pkt);
- break;
- case ACTION_WRITE:
- WriteClipboard(Pkt);
- break;
- /* case ACTION_SEEK:
- SeekClipboard(Pkt);*/
- break;
- case ACTION_DIE:
- if(OpenCount)
- {
- Pkt->dp_Res1=DOSFALSE;
- Pkt->dp_Res2=ERROR_OBJECT_IN_USE;
- }
- else
- {
- Pkt->dp_Res1=DOSTRUE;
- Pkt->dp_Res2=0;
- Done=TRUE;
- }
- case ACTION_IS_FILESYSTEM:
- Pkt->dp_Res1=DOSFALSE;
- Pkt->dp_Res2=0;
- break;
- default:
- Pkt->dp_Res1=DOSFALSE;
- Pkt->dp_Res2=ERROR_ACTION_NOT_KNOWN;
- break;
- }
- ReplyPacket(Pkt,PacketPort);
- }
- DevNode->dn_Task=NULL; /* Switch off device */
-
- except(NO_PORT,DeleteMsgPort(PacketPort));
- except(NO_IFFPARSE,CloseLibrary(LocalIFFParseBase));
- except(NO_DEV,);
- return(0);
- } /* ClipHandler */
-
- STATIC struct DosPacket *WaitPacket(struct MsgPort *port)
- {
- WaitPort(port);
- return((struct DosPacket *)GetMsg(port)->mn_Node.ln_Name);
- } /* WaitPacket */
-
- STATIC VOID ReplyPacket(struct DosPacket *packet, struct MsgPort *port)
- {
- struct MsgPort *ReplyPort=packet->dp_Port;
-
- packet->dp_Port=port;
- packet->dp_Link->mn_Node.ln_Name=(STRPTR)packet;
- PutMsg(ReplyPort,packet->dp_Link);
- } /* ReplyPacket */
-
- STATIC VOID ReplyPacketRes(struct DosPacket *packet, struct MsgPort *port,
- LONG res1, LONG res2)
- {
- packet->dp_Res1=res1;
- packet->dp_Res2=res2;
- ReplyPacket(packet,port);
- } /* ReplyPacketRes */
-
- STATIC struct IFFHandle *OpenCH(struct DosPacket *packet)
- {
- CHAR Name[PATH_SIZE];
- STRPTR Str=(STRPTR)BADDR(packet->dp_Arg3);
- struct FileHandle *Handle=FH(packet->dp_Arg1);
- struct IFFHandle *IFF;
- LONG Unit;
-
- packet->dp_Res1=DOSFALSE;
- packet->dp_Res2=0;
- Handle->fh_Arg1=0;
- Handle->fh_Port=NULL; /* Non-interactive file */
-
- memcpy(Name,&Str[1],Str[0]); /* Copy data */
- Name[Str[0]]='\0'; /* NULL-terminate */
-
- Str=Name;
- if(Str=strchr(Str,':')) /* Device name given */
- Str++; /* Skip it */
- Unit=atol(Str); /* Convert to unit number */
-
- unless(IFF=AllocIFF())
- {
- packet->dp_Res2=ERROR_NO_FREE_STORE;
- throw(NO_IFF);
- }
- unless(IFF->iff_Stream=(ULONG)OpenClipboard(Unit))
- {
- packet->dp_Res2=ERROR_NO_FREE_STORE; /* FIX!!! */
- throw(NO_CLIPBOARD);
- }
- InitIFFasClip(IFF);
- Handle->fh_Arg1=(LONG)IFF;
- packet->dp_Res1=DOSTRUE;
- return(IFF);
-
- except(NO_CLIPBOARD,CloseClipboard((struct ClipboardHandle *)IFF->iff_Stream));
- except(NO_IFF,FreeIFF(IFF));
- return(NULL);
- } /* OpenCH */
-
- STATIC VOID CloseCH(struct IFFHandle *iff)
- {
- CloseClipboard((struct ClipboardHandle *)iff->iff_Stream);
- FreeIFF(iff);
- } /* CloseCH */
-
- STATIC LONG OpenInputCH(struct DosPacket *packet)
- {
- struct IFFHandle *IFF;
- LONG Error;
-
- try(IFF=OpenCH(packet),NO_HANDLE);
- try(!(Error=OpenIFF(IFF,IFFF_READ)),NO_IFF);
- try(!(Error=StopChunk(IFF,ID_FTXT,ID_CHRS)),IFF_ERROR);
- try(!(Error=ParseIFF(IFF,IFFPARSE_SCAN)),IFF_ERROR);
- return(1); /* Open succesfull */
-
- except(IFF_ERROR,);
- packet->dp_Res1=DOSFALSE;
- packet->dp_Res2=IFF2DOS(Error); /* Set result */
- except(NO_IFF,CloseIFF(IFF));
- except(NO_HANDLE,CloseCH(IFF));
- return(0); /* Open failed */
- } /* OpenInputCH */
-
- STATIC LONG OpenOutputCH(struct DosPacket *packet)
- {
- struct IFFHandle *IFF;
- LONG Error;
-
- try(IFF=OpenCH(packet),NO_HANDLE);
- try(!(Error=OpenIFF(IFF,IFFF_WRITE)),NO_IFF);
- try(!(Error=PushChunk(IFF,ID_FTXT,ID_FORM,IFFSIZE_UNKNOWN)),IFF_ERROR);
- try(!(Error=PushChunk(IFF,0,ID_CHRS,IFFSIZE_UNKNOWN)),IFF_ERROR);
- return(1); /* Open succesfull */
-
- except(IFF_ERROR,);
- packet->dp_Res1=DOSFALSE;
- packet->dp_Res2=IFF2DOS(Error); /* Set result */
- except(NO_IFF,CloseIFF(IFF));
- except(NO_HANDLE,CloseCH(IFF));
- return(0); /* Open failed */
- } /* OpenOutputCH */
-
- STATIC LONG OpenUpdateCH(struct DosPacket *packet)
- {
- struct IFFHandle *IFF;
- LONG Error;
-
- try(IFF=OpenCH(packet),NO_HANDLE);
- try(!(Error=OpenIFF(IFF,IFFF_WRITE)),NO_IFF);
- try(!(Error=StopChunk(IFF,ID_FTXT,ID_CHRS)),IFF_ERROR);
- try(!(Error=ParseIFF(IFF,IFFPARSE_SCAN)),IFF_ERROR); /* FIX: Should use write mode here */
- return(1); /* Open succesfull */
-
- except(IFF_ERROR,);
- packet->dp_Res1=DOSFALSE;
- packet->dp_Res2=IFF2DOS(Error); /* Set result */
- except(NO_IFF,CloseIFF(IFF));
- except(NO_HANDLE,CloseCH(IFF));
- return(0); /* Open failed */
- } /* OpenUpdateCH */
-
- STATIC LONG CloseIOUCH(struct DosPacket *packet)
- {
- struct IFFHandle *IFF=(struct IFFHandle *)packet->dp_Arg1;
-
- #if 0
- /* FIX:??? Check PopChunk() for errors */
- if(ftst(IFF->iff_Flags,IFFF_WRITE)) /* Write mode */
- if(PopChunk(IFF)==0) /* Close CHRS */
- PopChunk(IFF); /* Close FTXT */
- #endif
- CloseIFF(IFF);
- CloseCH(IFF);
- packet->dp_Res1=DOSTRUE;
- packet->dp_Res2=0;
- return(1);
- } /* CloseIOUCH */
-
- STATIC VOID ReadClipboard(struct DosPacket *packet)
- {
- struct IFFHandle *IFF=(struct IFFHandle *)packet->dp_Arg1;
- STRPTR Buffer=(STRPTR)packet->dp_Arg2;
- LONG Read=-1,Bytes=packet->dp_Arg3;
-
- packet->dp_Res1=-1;
- packet->dp_Res2=0;
-
- Read=ReadChunkBytes(IFF,Buffer,Bytes); /* Read into buffer */
- if(Read<0)
- packet->dp_Res2=IFF2DOS(Read);
- else
- packet->dp_Res1=Read;
- } /* ReadClipboard */
-
- STATIC VOID WriteClipboard(struct DosPacket *packet)
- {
- struct IFFHandle *IFF=(struct IFFHandle *)packet->dp_Arg1;
- STRPTR Buffer=(STRPTR)packet->dp_Arg2;
- LONG Written=-1,Bytes=packet->dp_Arg3;
-
- packet->dp_Res1=-1;
- packet->dp_Res2=0;
-
- Written=WriteChunkBytes(IFF,Buffer,Bytes); /* Write buffer */
- if(Written<0)
- packet->dp_Res2=IFF2DOS(Written);
- else
- packet->dp_Res1=Written;
- } /* WriteClipboard */
-
- STATIC VOID SeekClipboard(struct DosPacket *packet)
- {
- struct IFFHandle *IFF=(struct IFFHandle *)packet->dp_Arg1;
- struct ContextNode *CN;
- LONG Offset=packet->dp_Arg2,OffsetType=packet->dp_Arg3;
- LONG OldPos,NewPos=-1;
-
- packet->dp_Res1=-1;
- packet->dp_Res2=ERROR_SEEK_ERROR;
-
- unless(CN=CurrentChunk(IFF))
- return;
- unless(CN->cn_Type==ID_FTXT && CN->cn_ID==ID_CHRS)
- return;
-
- switch(OffsetType)
- {
- case OFFSET_BEGINNING:
- NewPos=Offset;
- break;
- case OFFSET_CURRENT:
- NewPos=CN->cn_Scan+Offset;
- break;
- case OFFSET_END:
- NewPos=CN->cn_Size-Offset;
- break;
- }
- if(NewPos>0 && NewPos<CN->cn_Size) /* Can seek */
- {
- OldPos=CN->cn_Scan;
- CN->cn_Scan=NewPos;
- packet->dp_Res1=OldPos;
- packet->dp_Res2=0;
- }
- } /* SeekClipboard */
-
- STATIC LONG IFF2DOS(LONG iffError)
- {
- LONG DOSError;
-
- switch(iffError)
- {
- case IFFERR_EOF:
- case IFFERR_EOC:
- case IFFERR_NOSCOPE:
- case IFFERR_MANGLED:
- case IFFERR_SYNTAX:
- case IFFERR_NOTIFF:
- DOSError=ERROR_OBJECT_WRONG_TYPE;
- break;
- case IFFERR_NOMEM:
- DOSError=ERROR_NO_FREE_STORE;
- break;
- case IFFERR_SEEK:
- DOSError=ERROR_SEEK_ERROR;
- break;
- case IFFERR_NOHOOK:
- DOSError=ERROR_NOT_IMPLEMENTED;
- break;
- default:
- DOSError=ThisProcessS->pr_Result2;
- break;
- }
- return(DOSError);
- } /* IFF2DOS */
-